package cn.com.bod.fas.common.utils;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @description 日期工具类
 * @author chenyuanxian
 * @date 2019年9月15日 下午4:21:41
 * @version 1.0.0
 * @Copyright (c) scfhdt
 */

@Slf4j
public class DateUtil {
    public static final String YYYY_MM_DD_MM_HH_SS = "yyyy-MM-dd HH:mm:ss";
    
    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    
    public static final String YYYYMMDD = "yyyyMMdd";
    
    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    
    public static final String YYYYMMDDMMHHSSSSS = "yyyyMMddHHmmssSSS";
    
    public static final String YYYY_MM_DD_HH_MM_SS_S = "yyyy-MM-dd HH:mm:ss S";

    public static final String YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss.SSS";
    
    /**
     * @description 获取日期加上天数后的日期.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:24:03
     * @param date 日期
     * @param day 天数
     * @return 加上天数后的日期
     */
    public static Date dateAddDay(Date date, int day) {
        return add(date, Calendar.DAY_OF_YEAR, day);
    }
    
    /**
     * @description 获取日期加上月数后的日期.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:25:58
     * @param date 日期
     * @param month 月数
     * @return 日期加上月数后的日期
     */
    public static Date dateAddMonth(Date date, int month) {
        return add(date, Calendar.MONTH, month);
    }
    
    /**
     * @description 获取日期加上年数后的日期.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:26:52
     * @param date 日期
     * @param year 年数
     * @return 日期加上年数后的日期
     */
    public static Date dateAddYear(Date date, int year) {
        return add(date, Calendar.YEAR, year);
    }
    
    /**
     * @description 日期转换为yyyy-MM-dd格式的字符串.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:28:49
     * @param date 日期
     * @return 格式化后的日期
     */
    public static String dateToString(Date date) {
        return dateToString(date, YYYY_MM_DD);
    }
    
    /**
     * @description 将日期按指定格式转成字符串.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:29:54
     * @param date 日期
     * @param pattern 格式
     * @return 指定格式化后的日期
     */
    public static String dateToString(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }
    
    /**
     * @description 将日期转换为中文.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:32:10
     * @param date 日期
     * @return 中文日期
     */
    public static String dateToChineseString(Date date) {
        return dateToString(date, "yyyy年MM月dd日");
    }
    
    /**
     * @description 获取当前日期的前n天.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:34:53
     * @param days 天数
     * @return 格式化为yyyy-MM-dd的前n天日期
     */
    public static String getPreviousDay(int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, days); // 得到前n天
        Date date = calendar.getTime();
        SimpleDateFormat df = new SimpleDateFormat(YYYY_MM_DD);
        return df.format(date);
    }
    
    /**
     * @description 获取Date类型的日期.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:48:29
     * @param strDate 字符串格式的日期
     * @return Date类型的日期
     */
    public static Date strParseDate(String strDate) {
        Date date = null;
        try {
            date = new SimpleDateFormat(DateUtil.YYYY_MM_DD).parse(strDate);
        } catch (ParseException ex) {
//            log.info("日期格式化异常：{}", ExceptionUtils.getStackTrace(ex));
        }
        
        return date;
    }

    private static Date add(Date date, int type, int value) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(type, value);
        return calendar.getTime();
    }
    
    /**
     * @description 获取系统日期.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:39:54
     * @return 系统日期
     */
    public static String getSystemDate() {
        String systemDate = "";
        
        Date currentDate = new Date();
        SimpleDateFormat df = new SimpleDateFormat(YYYY_MM_DD_MM_HH_SS);
        systemDate = df.format(currentDate).substring(0, 10);
        
        return systemDate;
    }
    
    /**
     * @description 获取日期所在月份的第一天.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:41:40
     * @param date 日期
     * @return 日期所在月份第一天
     */
    public static Date getFirstDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);  
        calendar.set(Calendar.DAY_OF_MONTH, 1);  
        return calendar.getTime();     
    }
    
    /**
     * @description 获取YYYY-MM-DD格式的字符串日期所在月份的第一天.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:51:34
     * @param ymd YYYY-MM-DD格式字符串
     * @return 日期所在月份第一天
     */
    public static String getFirstDayOfMonth(String ymd) {
        Date date = strParseDate(ymd);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        Date retDate =  calendar.getTime();
        String ret = dateToString(retDate);
        return ret;
    }
    
    /**
     * @description 获取YYYY-MM-DD格式的字符串日期所在月份的上月月份.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:52:55
     * @param ymd YYYY-MM-DD格式字符串
     * @return 日期所在上月月份
     */
    public static String getLastMonth(String ymd) {
        String firstDay = getFirstDayOfMonth(ymd);
        Date date = strParseDate(firstDay);
        Date lastDay = dateAddDay(date, -1);
        String strLastDay = dateToString(lastDay, "YYYY-MM-DD");
        String month = strLastDay.substring(0, 7);
        
        return month;
    }
    
    /**
     * @description 获取日期所在月份的最后一天.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:56:33
     * @param date 日期
     * @return 日期所在月份的最后一天
     */
    public static Date getLastDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1); //加一个月
        calendar.set(Calendar.DAY_OF_MONTH, 1);  //设置为该月第一天
        calendar.add(Calendar.DATE, -1); //再减一天即为当月最后一天
        
        return calendar.getTime();
    }
    
    /**
     * @description 获取YYYY-MM-DD格式的字符串日期所在月份的最后一天.
     * @author chenyuanxian
     * @date 2019年9月15日 下午4:59:25
     * @param ymd YYYY-MM-DD格式字符串
     * @return 日期所在月份的最后一天
     */
    public static String getLastDayOfMonth(String ymd) {
        Date date = strParseDate(ymd);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1); //加一个月
        calendar.set(Calendar.DAY_OF_MONTH, 1);  //设置为该月第一天
        calendar.add(Calendar.DATE, -1); //再减一天即为当月最后一天
        Date retDate =  calendar.getTime();
        String ret = dateToString(retDate);
        return ret;
    }
    
    /**
     * @description 获取昨天所在的月份.
     * @author chenyuanxian
     * @date 2019年9月15日 下午5:03:28
     * @return 昨天所在的月份
     */
    public static String getYesterdayMonth() {
        String yesterday = getPreviousDay(-1);
        String month = yesterday.substring(0, 7);
        
        return month;
    }
    
    /**
     * @description 获取所在年份第一天日期.
     * @author chenyuanxian
     * @date 2019年9月15日 下午5:05:02
     * @param year 年份
     * @return 所在年份第一天日期
     */
    public static Date getYearFirstDay(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * @description 将日期格式化为指定格式.
     * @author chenyuanxian
     * @date 2019年9月15日 下午5:06:34
     * @param date 日期
     * @param dtFormat 格式字符串
     * @return 格式化后的日期
     */
    public static String fmtDateToStr(Date date, String dtFormat) {
        if (date == null) {
            return "";
        }
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(dtFormat);
            return dateFormat.format(date);
        } catch (Exception ex) {
//            log.info("日期格式化异常：{}", ExceptionUtils.getStackTrace(ex));
            return "";
        }
    }
    
    /**
     * @description 获取当前日期.
     * @author chenyuanxian
     * @date 2019年9月15日 下午5:08:47
     * @param dtFormat 格式
     * @return 格式化的当前日期
     */
    public static String getCurrentDate(String dtFormat) {
        Date date = new Date();
        return fmtDateToStr(date, dtFormat);
    }
}
